package cn.foolishbird.crow.enumeration;

import cn.foolishbird.crow.core.CrowEnum;
import cn.foolishbird.crow.core.cache.WeakCache;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.Objects;

/**
 * @author foolish-bird
 */
public final class CrowEnumUtils {

    private static final Logger log = LoggerFactory.getLogger(CrowEnumUtils.class);

    private static final WeakCache<Class<Enum<? extends CrowEnum>>, Map<Integer, Enum<? extends CrowEnum>>>
            CROW_ENUM_MAP = new WeakCache<>();

    private CrowEnumUtils() {

    }

    /**
     * 值转换成枚举
     *
     * @param value 枚举值
     * @param clz   枚举class
     * @return 枚举对象
     */
    public static Enum<? extends CrowEnum> toEnum(int value, Class<Enum<? extends CrowEnum>> clz) {
        Map<Integer, Enum<? extends CrowEnum>> enumMap = CROW_ENUM_MAP.get(clz);
        if (Objects.isNull(enumMap)) {
            Enum[] enums = clz.getEnumConstants();
            if (ArrayUtils.isEmpty(enums)) {
                log.error("枚举对象不能为空, 枚举名：{}", clz.getName());
                throw new IllegalArgumentException("不存在该枚举值");
            }

            Map<Integer, Enum<? extends CrowEnum>> map = Maps.newHashMapWithExpectedSize(enums.length);

            for (Enum e : enums) {
                CrowEnum crowEnum = (CrowEnum) e;
                map.put(crowEnum.value(), e);
            }

            CROW_ENUM_MAP.put(clz, map);

            enumMap = map;
        }

        Enum<? extends CrowEnum> v = enumMap.get(value);
        if (Objects.isNull(v)) {
            log.error("不存在该枚举值, 枚举名：{}, value:{}", clz.getName(), value);
            throw new IllegalArgumentException("不存在该枚举值");
        }
        return v;
    }

    /**
     * 枚举转换成boolean
     * 默认值 1是true，其他是false
     *
     * @param e 枚举值
     * @return Boolean 枚举转变成boolean 返回
     */
    public static Boolean toBoolean(Enum<? extends CrowEnum> e) {
        if (Objects.isNull(e)) {
            return false;
        }
        int value = ((CrowEnum) e).value();
        return 1 == value;
    }

}
